import 'dart:async';
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:reader_app/utils/permission_helper.dart';

///权限对话框
class PermissionDialog extends StatefulWidget {
  ///检查并请求权限，如果没有请求的相关权限组的权限会想用户直接申请，并处理申请拒绝的逻辑
  ///[showTipDialog] 推荐使用 Platform.isAndroid
  static Future<bool> checkAndRequestPermission(BuildContext context, List<PermissionGroup> permissions,
      {bool showTipDialog = false}) async {
    if (null == permissions || permissions.isEmpty) {
      return Future.delayed(Duration(seconds: 1), () {
        return false;
      });
    }

    var hasGranted = await PermissionHelper.instance().checkPermissionsHasGranted(permissions);
    if (hasGranted) {
      //已获得授权
      return Future.delayed(Duration(milliseconds: 1), () {
        return true;
      });
    } else {
      //未获得授权
      if (showTipDialog) {
        var result = await Navigator.push(
            context,
            _PopRoute(
                child: PermissionDialog(
              permissions: permissions,
            )));
        if (null != result && result is bool && result) {
          //用户授予了权限
          return Future.delayed(Duration(seconds: 1), () {
            return true;
          });
        }
      }
      return Future.delayed(Duration(milliseconds: 1), () {
        return false;
      });
    }
  }

  final List<PermissionGroup> permissions;

  const PermissionDialog({Key key, this.permissions}) : super(key: key);

  @override
  State<StatefulWidget> createState() => PermissionDialogState();
}

class PermissionDialogState extends State<PermissionDialog> with WidgetsBindingObserver {
  bool hasDenied = false;
  bool needOpenSetting = false;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    if (state == AppLifecycleState.resumed && needOpenSetting) {
      var hasGranted = await PermissionHelper.instance().checkPermissionsHasGranted(widget.permissions);
      Navigator.pop(context, null != hasGranted && hasGranted);
    }
  }

  @override
  Widget build(BuildContext context) {
    var title = hasDenied ? "应用权限缺失" : "提示";
    var hit = needOpenSetting ? "应用需要您到设置中授予部分权限，才能正常运行，请您授予应用相关权限" : "应用需要您授予部分权限，才能正常运行，请您授予应用相关权限";
    if (Platform.isIOS) {
      hit = "应用需要您到设置中授予部分权限，才能正常运行，请您授予应用相关权限";
    }
    return new Scaffold(
      backgroundColor: Colors.black54,
      body: new Center(
        child: Container(
          decoration: new BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.all(Radius.circular(8)),
          ),
          width: MediaQuery.of(context).size.width - 60,
          child: new Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new Padding(
                padding: EdgeInsets.all(15),
                child: new Text(
                  title,
                  style: new TextStyle(fontSize: 18, color: hasDenied ? Colors.red[400] : Colors.black54),
                ),
              ),
              new Padding(
                padding: EdgeInsets.only(top: 20, bottom: 30, left: 15, right: 15),
                child: new Text(
                  hit,
                  style: new TextStyle(fontSize: 16, color: Colors.black54),
                ),
              ),
              new Divider(
                height: 1,
                thickness: 1,
                color: Colors.grey[300],
              ),
              new Container(
                height: 45,
                child: new Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    new Expanded(
                        child: new InkWell(
                      onTap: () {
                        Navigator.pop(context, false);
                      },
                      child: new Center(
                        child: new Text(
                          "取消",
                          style: new TextStyle(fontSize: 16, color: Colors.black54),
                        ),
                      ),
                    )),
                    new SizedBox(
                      height: 45,
                      width: 1,
                      child: new VerticalDivider(
                        width: 1,
                        thickness: 1,
                        color: Colors.grey[300],
                      ),
                    ),
                    new Expanded(
                        child: new InkWell(
                      onTap: () async {
                        if (Platform.isIOS) {
                          Navigator.pop(context, false);
                          return;
                        }

                        if (!hasDenied) {
                          //1、直接申请
                          await PermissionHelper.instance().requestPermission(widget.permissions).then((result) async {
                            bool hasAllGranted = true;
                            //todo 可加强制获取，否则退出应用
                            if (null == result || result.isEmpty) {
                              hasAllGranted = false;
                            } else {
                              result.forEach((key, value) {
                                if (value != PermissionStatus.granted) {
                                  hasAllGranted = false;
                                }
                              });
                            }

                            if (hasAllGranted) {
                              Navigator.pop(context, true);
                            } else {
                              var canRequestPermission =
                                  await PermissionHelper.instance().shouldShowRequestPermissionRationale(widget.permissions);
                              setState(() {
                                hasDenied = true;
                                needOpenSetting = !canRequestPermission;
                              });
                            }
                          });
                        } else {
                          //2、直接申请拒绝，或者仍有部分权限未授予
                          var isShow = await PermissionHelper.instance().shouldShowRequestPermissionRationale(widget.permissions);
                          if (!needOpenSetting) {
                            //可以申请
                            var result = await PermissionHelper.instance().requestPermission(widget.permissions);
                            bool hasAllGranted = true;
                            result.forEach((key, value) {
                              if (value != PermissionStatus.granted) {
                                hasAllGranted = false;
                              }
                            });
                            Navigator.pop(context, hasAllGranted);
                          } else {
                            //只能去设置页面手动打开
                            PermissionHelper.instance().openSetting();
                          }
                        }
                      },
                      child: new Center(
                        child: new Text(
                          "确定",
                          style: new TextStyle(fontSize: 16, color: Colors.black),
                        ),
                      ),
                    )),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }
}

class _PopRoute<int> extends PopupRoute {
  final Duration _duration = Duration(milliseconds: 300);
  Widget child;

  _PopRoute({@required this.child});

  @override
  Color get barrierColor => null;

  @override
  bool get barrierDismissible => true;

  @override
  get barrierLabel => null;

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    return child;
  }

  @override
  Duration get transitionDuration => _duration;
}
